package com.iking.housekeeping.controller.menu;

import java.util.ArrayList;
import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.iking.housekeeping.common.CodeEnum;
import com.iking.housekeeping.common.ReturnCode;
import com.iking.housekeeping.entity.menu.SysMenu;
import com.iking.housekeeping.httpbean.login.reqbean.LoginParam;
import com.iking.housekeeping.httpbean.menu.resbean.ReturnSysMenu;
import com.iking.housekeeping.service.menu.MenuService;
import com.iking.housekeeping.service.user.LoginService;
import com.iking.housekeeping.util.CodeUtil;
import com.iking.housekeeping.util.UUIDUtil;

/**
 * 菜单管理
 * 
 * @author 秦甫杰
 *
 */
@RestController
@RequestMapping("/menu")
public class MenuController {
	
	@Autowired
	private MenuService menuService;
	
	@Autowired
	private LoginService loginService;

	/**
	 * 获取全部菜单
	 * 
	 * @return
	 */
	@GetMapping(value = "/getAll")
	public ReturnCode getAllMenu() {
		// 获取所有菜单列表
		List<ReturnSysMenu> sysMenuList = menuService.getAllMenu();
		// 将菜单列表转换为树结构
		// 查询所有的父级菜单列表
		sysMenuList = menuService.getMenuTree(sysMenuList, "");
		return new ReturnCode(CodeEnum.SUCCESS, sysMenuList);
	}
	
	/**
	 * 	获取用户菜单
	 *  @param fLoginName
	 *  @return ReturnCode
	 * @author: gf
	 */
	@PostMapping("/getLoginMenu")
	public ReturnCode getLoginMenu(@RequestBody @Valid LoginParam loginParam) {
		// 获取用户所有菜单
		List<SysMenu> sysMenuList = loginService.getMenuByLoginName(loginParam.getfLoginName());
		// 将菜单列表转换为树结构
		// 查询所有的父级菜单列表
		List<ReturnSysMenu> returnSysMenu = new ArrayList<ReturnSysMenu>();
		for (SysMenu sysMenu : sysMenuList) {
			ReturnSysMenu returnMenu = new ReturnSysMenu();
			returnMenu.setfId(sysMenu.getfId());
			returnMenu.setfMenuIcon(sysMenu.getfMenuIcon());
			returnMenu.setfMenuName(sysMenu.getfMenuName());
			returnMenu.setfAddress(sysMenu.getfAddress());
			returnMenu.setfMenuCode(sysMenu.getfMenuCode());
			returnMenu.setfMenuPCode(sysMenu.getfMenuPCode());
			returnMenu.setfIsButton(sysMenu.getfIsButton());
			returnMenu.setfIsAvailable(sysMenu.getfIsAvailable());
			returnSysMenu.add(returnMenu);
		}
		List<ReturnSysMenu> menuTree = menuService.getMenuTree(returnSysMenu, "");
		return new ReturnCode(CodeEnum.SUCCESS, menuTree);
	}

	/**
	 * 添加菜单
	 */
	@PostMapping("/insertMenu")
	public ReturnCode insertMenu(@RequestBody @Valid SysMenu sysMenu, BindingResult bindingResult) {
		// 判断参数是否合法
		if (bindingResult.hasErrors()) {
			String msg = bindingResult.getFieldError().getDefaultMessage();
			return new ReturnCode(CodeEnum.FAIL, msg, null);
		}
		//根据菜单名查看菜单是否存在，存在则不能添加
		SysMenu sysMenu1 = menuService.selectSysMenuByName(sysMenu.getfMenuName());
		if (sysMenu1 != null) {
			return new ReturnCode(CodeEnum.FAIL, null);
		}
		// 判断传入的父级按钮是否为父级
		if(sysMenu.getfMenuPCode() != null || !"".equals(sysMenu.getfMenuPCode())) {
			//
			SysMenu sysmenu1 = menuService.selectMenuByCode(sysMenu.getfMenuPCode());
			if(sysmenu1.getfIsButton()==true) {
				return new ReturnCode(CodeEnum.FAIL);
			}
		}
		// 查询当前父级菜单下的所有子菜单
		List<SysMenu> sysMenuList = menuService.selectByPCode(sysMenu.getfMenuPCode());
		/**
		 * 通过父级菜单和查询到子级菜单的长度获取正确的编号信息
		 */
		sysMenu.setfMenuCode(CodeUtil.getCodeByPCode(sysMenu.getfMenuPCode(), sysMenuList.size()));
		// 设置数据为未删除
		sysMenu.setfId(UUIDUtil.getUUID());
		sysMenu.setfIsDeleted(false);
		sysMenu.setfIsButton(false);
		//添加失败返回fail
		if (menuService.insertMenu(sysMenu) == 0) {
			return new ReturnCode(CodeEnum.FAIL, null);
		}
		return new ReturnCode(CodeEnum.SUCCESS);
	}

	/**
	 * 删除菜单
	 * 
	 * @param fId
	 * @return
	 */
	@GetMapping("/delmenu/{fId}")
	public ReturnCode delMenu(@PathVariable("fId") String fId) {
		//判断传入的参数是否存在
		if(fId == null || fId.trim().equals("")) {
			return new ReturnCode(CodeEnum.FAIL);
		}
		// 1根据id查询当前要删除菜单的所有信息
		SysMenu sysMenu = menuService.selectMenuById(fId);
		// 2根据查询到要删除的菜单的子菜单放入到父级菜单中
		List<SysMenu> menuChildren = menuService.selectByPCode(sysMenu.getfMenuCode());
		// 3对查询到的内容进行判断如果查询到的长度大于0说明该父级菜单下有数据，则不能删除，反之可以删除
		if (menuChildren.size() > 0) {
			return new ReturnCode(CodeEnum.FAIL);
		}
		menuService.delMenuByCode(fId);
		// 4根据已删除的菜品信息的pCode查询所有的同级菜单
		List<SysMenu> munuList = menuService.selectByPCode(sysMenu.getfMenuPCode());
		// 5遍历当前所获得的同级菜单
		String oldFMenuCode;
		String newFMenuCode;
		// 对菜单进行排序
		for (int i = 0; i < munuList.size(); i++) {
			// 获取当前的父级菜单编号
			oldFMenuCode = munuList.get(i).getfMenuCode();
			if (i + 1 == CodeUtil.getIndexByCode(oldFMenuCode)) {
				continue;
			}
			newFMenuCode = CodeUtil.getCodeByCode(oldFMenuCode, i);
			menuService.changeSysMenuCode(munuList.get(i), newFMenuCode);
		}
		List<SysMenu> sortList = menuService.selectByPCode(sysMenu.getfMenuPCode());
		menuService.soltSysMenuList(sortList);
		return new ReturnCode(CodeEnum.SUCCESS);
	}

	/**
	 * 根据ID查询菜单
	 */
	@GetMapping("/selectMenuById/{fId}")
	public ReturnCode selectMenuById(@PathVariable("fId") String fId) {
		//判断传入的参数是否存在
		if(fId == null || fId.trim().equals("")) {
			return new ReturnCode(CodeEnum.FAIL, null);
		}
		SysMenu sysMenu = menuService.selectMenuById(fId);
		if (sysMenu == null) {
			return new ReturnCode(CodeEnum.FAIL, null);
		}
		return new ReturnCode(CodeEnum.SUCCESS, sysMenu);
	}

	/**
	 * 根据id更新菜单
	 */
	@PostMapping("/updateMenu")
	public ReturnCode updateMenuById(@RequestBody SysMenu sysMenu, BindingResult bindingResult) {
		// 判断参数是否合法
		if (bindingResult.hasErrors()) {
			String msg = bindingResult.getFieldError().getDefaultMessage();
			return new ReturnCode(CodeEnum.FAIL, msg, null);
		}
		// 根据id查询菜单
		SysMenu thisMenu = menuService.selectMenuById(sysMenu.getfId());
		//如果要修改为按钮的话
		if(sysMenu.getfIsButton()==true) {
			List<SysMenu> listMenu=menuService.selectByPCode(thisMenu.getfMenuCode());
			//如果此菜单有子集或者此菜单为本身就为按钮则不能修改
			if(listMenu.size()>0 || thisMenu.getfIsButton() == true) {
				return new ReturnCode(CodeEnum.FAIL, null);
			}
		}
		// 如果要更新的菜单的父级菜单等于更新菜单的父级ID
		if (sysMenu.getfMenuPCode().equals(thisMenu.getfMenuPCode())) {
			menuService.updateMenu(sysMenu);
		} else {
			// 根据要更改的父节点查询下面所有的子节点
			List<SysMenu> pChildren = menuService.selectByPCode(sysMenu.getfMenuPCode());
			// 定义一个新添加的子节点
			String fMenuCode;
			// 如果子节点的长度大于0并且小于9
			fMenuCode = CodeUtil.getCodeByPCode(sysMenu.getfMenuPCode(), pChildren.size());
			// 更改子菜单的编号fMenuCode
			sysMenu.setfMenuCode(fMenuCode);
			// 更新当前子菜单的编号
			menuService.updateMenu(sysMenu);
			// 获取当前
			List<SysMenu> oldPChildren = menuService.selectByPCode(thisMenu.getfMenuPCode());
			menuService.soltSysMenuList(oldPChildren);
		}
		return new ReturnCode(CodeEnum.SUCCESS, null);
	}

	/**
	 * 根据两个id对数据进行变更
	 */
	@GetMapping("/changePCode/{fIdOne}/{fIdTwo}")
	public ReturnCode changePCode(@PathVariable("fIdOne") String fIdOne, @PathVariable("fIdTwo") String fIdTwo) {
		// 判断参数是否为空
		if(fIdOne == null || fIdOne.trim().equals("") || fIdTwo == null || fIdTwo.trim().equals("")) {
			return new ReturnCode(CodeEnum.FAIL);
		}
		// 首先分别根据两个id查询所有的菜单信息
		SysMenu sysMenu1 = menuService.selectMenuById(fIdOne);
		SysMenu sysMenu2 = menuService.selectMenuById(fIdTwo);
		String fMenuCode1 = sysMenu1.getfMenuCode().substring(0, 2);
		String fMenuCode2 = sysMenu2.getfMenuCode().substring(0, 2);
		// 根据fcode的前两位进行迷糊查询
		List<SysMenu> menuList1 = menuService.selectSysMenuByFCode(fMenuCode1);
		List<SysMenu> menuList2 = menuService.selectSysMenuByFCode(fMenuCode2);
		String indexCode;
		String pCode;
		// 遍历查询到的结果，如果sysMenu1中的
		for (SysMenu sysMenu : menuList1) {
			indexCode = sysMenu.getfMenuCode();
			pCode = sysMenu.getfMenuPCode();
			if (!fMenuCode1.equals(sysMenu.getfMenuCode())) {
				/*sysMenu.setfMenuPCode(
						sysMenu2.getfMenuCode() + pCode.substring(sysMenu2.getfMenuCode().length(), pCode.length()));
				sysMenu.setfMenuCode(sysMenu2.getfMenuCode()
						+ indexCode.substring(sysMenu2.getfMenuCode().length(), indexCode.length()));*/
				sysMenu.setfMenuPCode(fMenuCode2+pCode.substring(fMenuCode2.length(), pCode.length()));
				sysMenu.setfMenuCode(fMenuCode2+indexCode.substring(fMenuCode2.length(), indexCode.length()));
			} else {
				sysMenu.setfMenuCode(fMenuCode2);
			}
			menuService.updateMenu(sysMenu);
		}
		for (SysMenu sysMenu : menuList2) {
			indexCode = sysMenu.getfMenuCode();
			pCode = sysMenu.getfMenuPCode();
			if (!fMenuCode2.equals(sysMenu.getfMenuCode())) {
				/*sysMenu.setfMenuPCode(
						sysMenu1.getfMenuCode() + pCode.substring(sysMenu1.getfMenuCode().length(), pCode.length()));
				sysMenu.setfMenuCode(sysMenu1.getfMenuCode()
						+ indexCode.substring(sysMenu1.getfMenuCode().length(), indexCode.length()));*/
				sysMenu.setfMenuPCode(fMenuCode1+pCode.substring(fMenuCode1.length(), pCode.length()));
				sysMenu.setfMenuCode(fMenuCode1+indexCode.substring(fMenuCode1.length(), indexCode.length()));
			} else {
				sysMenu.setfMenuCode(fMenuCode1);
			}
			menuService.updateMenu(sysMenu);
		}
		return new ReturnCode(CodeEnum.SUCCESS);
	}
}
